package com.irdstudio.efp.esb.api.service.sed.ploaninfo;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.irdstudio.basic.framework.core.constant.DblStEnum;
import com.irdstudio.basic.framework.core.constant.EsbRetCodeStandard;
import com.irdstudio.basic.framework.core.constant.SDicCertTypeEnum;
import com.irdstudio.basic.framework.core.exception.BizException;
import com.irdstudio.basic.framework.core.util.AccLoanStatusUtils;
import com.irdstudio.basic.framework.core.util.DateUtility;
import com.irdstudio.efp.cus.service.facade.CusIndivService;
import com.irdstudio.efp.esb.api.bean.sed.ploaninfo.MsgInfoArry;
import com.irdstudio.efp.esb.api.bean.sed.ploaninfo.YedReqPersonalLoanInfo;
import com.irdstudio.efp.esb.api.bean.sed.ploaninfo.YedRespPersonalLoanInfo;
import com.irdstudio.efp.esb.api.common.EsbRespServiceBeanCreator;
import com.irdstudio.efp.esb.api.common.sed.PersonalLoanQryTypeEnum;
import com.irdstudio.efp.esb.common.constant.EsbSysHeadEnums;
import com.irdstudio.efp.esb.common.server.req.EsbReqServiceBean;
import com.irdstudio.efp.esb.common.server.resp.EsbRespServiceBean;
import com.irdstudio.efp.esb.service.bo.req.hj.ReqLoanBalanceBean;
import com.irdstudio.efp.esb.service.bo.req.hj.ReqLoanInfoQueryBean;
import com.irdstudio.efp.esb.service.bo.req.hj.ReqRepaymentDetailsInfoQueryBean;
import com.irdstudio.efp.esb.service.bo.resp.hj.*;
import com.irdstudio.efp.esb.service.facade.hj.LoanInfoQueryService;
import com.irdstudio.efp.loan.service.vo.AccLoanStatisticalInfo;
import com.irdstudio.efp.loan.service.vo.AccLoanVO;
import com.irdstudio.efp.nls.service.facade.NlsApplyInfoService;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.function.Predicate;


/**
 * @author
 * @version 0.1
 * @date 2020-08-05
 */
@Service("yedPersonalLoanInfoService")
public class YedPersonalLoanInfoService {

    private static Logger logger = LoggerFactory.getLogger(YedPersonalLoanInfoService.class);

    @Autowired
    @Qualifier("cusIndivService")
    private CusIndivService cusIndivService;

    // 默认第一页
    private final String DEFAULT_PAGE_NO = "1";
    // 默认每页显示10条记录
    private final String DEFAULT_PAGE_SIZE = "10";

    /**
     * 借据状态数组
     * 0	出帐未确认
     * 1	正常
     * 10	逾期
     * 11	理赔结清
     * 12	撤销
     * 13	代偿结清
     * 14	非应计
     * 2	冲正
     * 3	失败
     * 4	结清
     * 5	销户
     * 6	垫款
     * 7	已扣款
     * 8	置换
     * 9	核销
     */
    private final String[] dblStArr = {"0", "1", "10", "11", "2", "3", "4", "5", "6", "7", "8", "9", "12", "13", "14"};

    /**
     * 交易流水号预言为空
     */
    private final Predicate<YedReqPersonalLoanInfo> oriTxnFlowNoPredicate = (p) -> StringUtils.isEmpty(p.getUseCrdtAppSrlNo());
    /**
     * 授信协议编号预言为空
     */
    private final Predicate<YedReqPersonalLoanInfo> crdAgrmNoPredicate = (p) -> StringUtils.isEmpty(p.getCrAgrmtNo());
    /**
     * 客户号预言为空
     */
    private final Predicate<YedReqPersonalLoanInfo> clntNoPredicate = (p) -> StringUtils.isEmpty(p.getCustNo());
    /**
     * 证件类型预言为空 或者 非法的证件类型
     */
    private final Predicate<YedReqPersonalLoanInfo> certTpPredicate = (p) -> {
        if (StringUtils.isEmpty(p.getIdentTp())) {
            return true;
        }
        //非法的证据类型也返回true
        SDicCertTypeEnum[] values = SDicCertTypeEnum.values();
        List<SDicCertTypeEnum> sDicCertTypeEnums = Arrays.asList(values);
        for (SDicCertTypeEnum sDicCertTypeEnum : sDicCertTypeEnums) {
            if (sDicCertTypeEnum.getValue().equals(p.getIdentTp())) {
                return false;
            }
        }
        return true;
    };
    /**
     * 证件号码预言为空
     */
    private final Predicate<YedReqPersonalLoanInfo> certNoPredicate = (p) -> StringUtils.isEmpty(p.getIdentNo());
    /**
     * 产品id预言为空
     */
    private final Predicate<YedReqPersonalLoanInfo> prdctIdPredicate = (p) -> StringUtils.isEmpty(p.getPdNo());

    /**
     * 借据状态预言为空 或者 借据状态非法
     */
    private final Predicate<YedReqPersonalLoanInfo> dblStPredicate = (p) -> {
        if (StringUtils.isEmpty(p.getDbllSt())) {
            return true;
        }

        if (!Arrays.asList(dblStArr).contains(p.getDbllSt())) {
            return true;
        }

        return false;
    };

    /**
     * 渠道号预言为空 或者 渠道号非法
     */
    private final Predicate<YedReqPersonalLoanInfo> chanNoPredicate = (p) -> {
        if (StringUtils.isEmpty(p.getChanNo())) {
            return true;
        }

        return false;
    };

    /**
     * 预言产品Id、渠道编号、审批状态 至少一个字段有值
     */
    private final Predicate<YedReqPersonalLoanInfo> prdAndCnoAndStPredicate = (p) -> {
        return !prdctIdPredicate.test(p) || !chanNoPredicate.test(p) || !dblStPredicate.test(p);
    };

    /**
     * 发生异常时候封装EsbRespServiceBean
     *
     * @param esbReqServiceBean
     * @param exception
     * @param pageNo
     * @param pageSize
     * @param respPersonalLoanInfo
     * @return
     */
    public EsbRespServiceBean getEsbRespServiceBean(EsbReqServiceBean esbReqServiceBean, Exception exception, String pageNo, String pageSize, YedRespPersonalLoanInfo respPersonalLoanInfo, EsbRetCodeStandard esbRetCodeStandard) {
        logger.error("借据信息查询发生异常：" + exception.getMessage());
        //需要反馈异常信息给esb
        logger.info("借据信息查询发生异常处理开始");
        respPersonalLoanInfo.setPgNo(pageNo);
        //当返回异常时，设置查询到的记录数为0
        respPersonalLoanInfo.setTotCnt("0");
        respPersonalLoanInfo.setPerPgDsplCnt(pageSize);
        respPersonalLoanInfo.setRetCd(esbRetCodeStandard.getValue());
        respPersonalLoanInfo.setRetMsg(exception.getMessage());
        respPersonalLoanInfo.setMsgInfoArryList(new ArrayList<MsgInfoArry>());
        logger.info("借据信息查询发生异常处理结束");
        exception.printStackTrace();
        return EsbRespServiceBeanCreator.buildesbRespServiceBean(esbReqServiceBean,
                JSONObject.toJSONString(respPersonalLoanInfo, SerializerFeature.WriteMapNullValue, SerializerFeature.WriteNullListAsEmpty, SerializerFeature.WriteNullStringAsEmpty, SerializerFeature.WriteNullNumberAsZero, SerializerFeature.WriteMapNullValue),
                EsbSysHeadEnums.RetStEnum.FAILURE.getCode(),
                esbRetCodeStandard.getValue(),
                exception.getMessage());
    }


    /**
     * 根据查询类型封装查询参数
     *
     * @param qryType             查询类型
     * @param reqPersonalLoanInfo
     * @throws Exception
     */
    public AccLoanVO transferQueryParams(String qryType, YedReqPersonalLoanInfo reqPersonalLoanInfo) throws Exception {

        AccLoanVO accLoanVO = new AccLoanVO();
        switch (PersonalLoanQryTypeEnum.getQryType(qryType)) {
            case QUERY_TYPE_01: {
                //01.单笔借据信息查询--必要查询条件:用信流水号(原交易流水号)、授信协议编号

                if (oriTxnFlowNoPredicate.test(reqPersonalLoanInfo) && crdAgrmNoPredicate.test(reqPersonalLoanInfo)) {
                    throw new BizException("用信流水号、授信协议编号不能为空");
                }
                if (oriTxnFlowNoPredicate.test(reqPersonalLoanInfo)) {
                    throw new BizException("用信流水号不能为空");
                }
                if (crdAgrmNoPredicate.test(reqPersonalLoanInfo)) {
                    throw new BizException("授信协议编号不能为空");
                }
                //流水号
                accLoanVO.setApplySeq(reqPersonalLoanInfo.getUseCrdtAppSrlNo());
                //借据号
                accLoanVO.setLmtContNo(reqPersonalLoanInfo.getCrAgrmtNo());
                break;
            }
            case QUERY_TYPE_02:
            case QUERY_TYPE_08:
            case QUERY_TYPE_09: {
                //02.单笔额度下所有的借据信息查询-授信协议编号必输
                if (crdAgrmNoPredicate.test(reqPersonalLoanInfo)) {
                    throw new BizException("授信协议编号不能为空");
                }
                accLoanVO.setLmtContNo(reqPersonalLoanInfo.getCrAgrmtNo());
                break;
            }
            case QUERY_TYPE_03: {
                //03.单笔额度下所有正常、逾期、结清、冲正、核销的借据申请信息-授信协议编号、借据状态必输

                if (crdAgrmNoPredicate.test(reqPersonalLoanInfo) && dblStPredicate.test(reqPersonalLoanInfo)) {
                    throw new BizException("授信协议编号、借据状态不能为空");
                }
                if (crdAgrmNoPredicate.test(reqPersonalLoanInfo)) {
                    throw new BizException("授信协议编号不能为空");
                }
                if (dblStPredicate.test(reqPersonalLoanInfo)) {
                    throw new BizException("借据状态不能为空");
                }
                accLoanVO.setLmtContNo(reqPersonalLoanInfo.getCrAgrmtNo());
                accLoanVO.setAccountStatus(reqPersonalLoanInfo.getDbllSt());
                break;
            }
            case QUERY_TYPE_04: {
                //04.单客户下所有的借据信息-证件类型、证件号码 必输
                if (certTpPredicate.test(reqPersonalLoanInfo) && certNoPredicate.test(reqPersonalLoanInfo)) {
                    throw new BizException("证件类型、证件号码不能为空");
                }
                if (certTpPredicate.test(reqPersonalLoanInfo)) {
                    throw new BizException("证件类型不能为空");
                }
                if (certNoPredicate.test(reqPersonalLoanInfo)) {
                    throw new BizException("证件号码不能为空");
                }
                accLoanVO.setCertType(reqPersonalLoanInfo.getIdentTp());
                accLoanVO.setCertCode(reqPersonalLoanInfo.getIdentNo());
                break;
            }
            case QUERY_TYPE_05: {
                //05.单笔客户下某个产品下所有的借据信息-证件类型，证件号码，产品id必输

                if (certTpPredicate.test(reqPersonalLoanInfo) || certNoPredicate.test(reqPersonalLoanInfo) || prdctIdPredicate.test(reqPersonalLoanInfo)) {
                    throw new BizException(getNullMsg(reqPersonalLoanInfo.getIdentTp(), reqPersonalLoanInfo.getIdentNo(), reqPersonalLoanInfo.getPdNo(), "证件类型", "证件号码", "产品ID"));
                }
                accLoanVO.setCertType(reqPersonalLoanInfo.getIdentTp());
                accLoanVO.setCertCode(reqPersonalLoanInfo.getIdentNo());
                accLoanVO.setPrdId(reqPersonalLoanInfo.getPdNo());
                break;
            }
            case QUERY_TYPE_06: {
                //06.单笔客户下某个渠道下所有的借据信息-证件类型，证件号码，渠道编号必输

                if (certTpPredicate.test(reqPersonalLoanInfo) || certNoPredicate.test(reqPersonalLoanInfo) || chanNoPredicate.test(reqPersonalLoanInfo)) {
                    throw new BizException(getNullMsg(reqPersonalLoanInfo.getIdentTp(), reqPersonalLoanInfo.getIdentNo(), reqPersonalLoanInfo.getChanNo(), "证件类型", "证件号码", "渠道编号"));
                }
                accLoanVO.setCertType(reqPersonalLoanInfo.getIdentTp());
                accLoanVO.setCertCode(reqPersonalLoanInfo.getIdentNo());
                accLoanVO.setChannelCode(reqPersonalLoanInfo.getChanNo());
                break;
            }
            case QUERY_TYPE_07: {
                // 07.单个客户下查询所有正常、逾期、结清、冲正、核销的借据信息-证件类型、证件号码、借据状态必输。

                if (certTpPredicate.test(reqPersonalLoanInfo) || certNoPredicate.test(reqPersonalLoanInfo) || dblStPredicate.test(reqPersonalLoanInfo)) {
                    throw new BizException(getNullMsg(reqPersonalLoanInfo.getIdentTp(), reqPersonalLoanInfo.getIdentNo(), reqPersonalLoanInfo.getDbllSt(), "证件类型", "证件号码", "借据状态"));
                }
                accLoanVO.setCertType(reqPersonalLoanInfo.getIdentTp());
                accLoanVO.setCertCode(reqPersonalLoanInfo.getIdentNo());
                accLoanVO.setAccountStatus(reqPersonalLoanInfo.getDbllSt());
                break;
            }
            default: {
                throw new BizException("你输入的查询类型有误，请重新输入");
            }
        }
        return accLoanVO;
    }

    private final String getNullMsg(String value1, String value2, String value3, String msg1, String msg2, String msg3) {
        String msg = "";
        if (StringUtils.isEmpty(value1)) {
            msg = msg + msg1 + "、";
        }
        if (StringUtils.isEmpty(value2)) {
            msg = msg + msg2 + "、";
        }
        if (StringUtils.isEmpty(value3)) {
            msg = msg + msg3 + "、";
        }

        if (StringUtils.isEmpty(msg)) {
            return "";
        }
        msg = msg.substring(0, msg.length() - 1);


        msg = msg + "不能为空";
        return msg;
    }

    /**
     * 预言输入的字符串为大于1的数字
     */
    private Predicate<String> checkIsNumberPredicate = (str) -> {

        if (str.matches("[0-9]*$") && Integer.parseInt(str) < 1) {

            return true;
        }
        return false;

    };

    /**
     * 处理查询到的数据
     *
     * @param accLoanVOList
     * @param qryType
     * @param pageNo
     * @param pageSize
     * @return
     * @throws Exception
     */
    public List<AccLoanVO> handleResultList(List<AccLoanVO> accLoanVOList, String qryType, String pageNo, String pageSize) throws Exception {
        int intPageNo = 0;
        int intPageSize = 0;
        int totalSize = accLoanVOList.size();
        //查询01 单个查询
        if (!PersonalLoanQryTypeEnum.QUERY_TYPE_01.getValue().equals(qryType)) {

            if (StringUtils.isEmpty(pageNo) || checkIsNumberPredicate.test(pageNo)) {
                // 没有传入页码或者页码非法时候默认第一页
                pageNo = DEFAULT_PAGE_NO;
            }
            if (StringUtils.isEmpty(pageSize) || checkIsNumberPredicate.test(pageSize)) {
                // 没有传入显示几行数据时，默认显示10条数据
                pageSize = DEFAULT_PAGE_SIZE;
            }
            intPageNo = Integer.valueOf(pageNo);
            intPageSize = Integer.valueOf(pageSize);
        } else {
            return accLoanVOList;
        }
        List<AccLoanVO> newAccLoanVO = new ArrayList<AccLoanVO>();
        for (int i = intPageSize * (intPageNo - 1); i < totalSize && i < intPageSize * intPageNo; i++) {
            newAccLoanVO.add(accLoanVOList.get(i));
        }
        return newAccLoanVO;
    }

    @Autowired
    private LoanInfoQueryService loanInfoQueryService;

    @Autowired
    private NlsApplyInfoService nlsApplyInfoService;

    public MsgInfoArry getLoanInfArry(AccLoanVO a, AccLoanStatisticalInfo b, String openDay, String glblSrlNo,String qryType) throws Exception {
        //这里的数据需要查询互金的实时接口获取 根据贷款号和发放号
        //获取用信流水号
        //NlsApplyInfoVO nlsApplyInfoPkParam = new NlsApplyInfoVO();
        //if (StringUtil.isNullorBank(a.getApplySeq())) {
        //    throw new Exception("用信流水号为空");
        //}
        //nlsApplyInfoPkParam.setApplySeq(a.getApplySeq());
        //NlsApplyInfoVO nlsApplyInfoVO = nlsApplyInfoService.queryByPk(nlsApplyInfoPkParam);
        //互金-借据信息查询
        ReqLoanInfoQueryBean reqLoanInfoQueryBean = new ReqLoanInfoQueryBean();
        reqLoanInfoQueryBean.setDistrNo(a.getDistrNo());
        reqLoanInfoQueryBean.setLoanNo(a.getLoanSeq());
        RespLoanInfoQueryBean respLoanInfoQueryBean = loanInfoQueryService.loanInfoQuery(reqLoanInfoQueryBean, glblSrlNo);
        //互金-借据余额查询
        ReqLoanBalanceBean reqLoanBalanceBean = new ReqLoanBalanceBean();
        reqLoanBalanceBean.setLoanNo(a.getLoanSeq());
        reqLoanBalanceBean.setDistrNo(a.getDistrNo());
        RespLoanBalanceQueryBean respLoanBalanceQueryBean = loanInfoQueryService.loanBalanceQuery(reqLoanBalanceBean, glblSrlNo);
        //查过查询互金的数据为空 那么抛出异常
        if (Objects.isNull(respLoanInfoQueryBean) || Objects.isNull(respLoanBalanceQueryBean)) {
            throw new RuntimeException("借据实时信息查询失败，请稍后再试");
        }
        //将vo的值设置daoloaninfarry
        MsgInfoArry msgInfoArry = null;
        //互金查回的账号状态
        String accStatusHj = AccLoanStatusUtils.transferAccStatusByHj(respLoanInfoQueryBean.getAcctStDsc(), respLoanBalanceQueryBean.getLoanSt());
        if (PersonalLoanQryTypeEnum.QUERY_TYPE_08.getValue().equals(qryType)) {
            if (accStatusHj.equals(DblStEnum.ENUM_4.getValue())) {
                msgInfoArry = setMsgInfoArray(a, openDay, glblSrlNo, respLoanInfoQueryBean, respLoanBalanceQueryBean);
            }
        } else if (PersonalLoanQryTypeEnum.QUERY_TYPE_09.getValue().equals(qryType)) {
            if ((accStatusHj.equals(DblStEnum.ENUM_1.getValue())
                    || accStatusHj.equals(DblStEnum.ENUM_10.getValue()) || accStatusHj.equals(DblStEnum.ENUM_14.getValue()))) {
                msgInfoArry = setMsgInfoArray(a, openDay, glblSrlNo, respLoanInfoQueryBean, respLoanBalanceQueryBean);
            }
        } else {
            msgInfoArry = setMsgInfoArray(a, openDay, glblSrlNo, respLoanInfoQueryBean, respLoanBalanceQueryBean);
        }
        return msgInfoArry;
    }

    private MsgInfoArry setMsgInfoArray(AccLoanVO a, String openDay, String glblSrlNo, RespLoanInfoQueryBean respLoanInfoQueryBean, RespLoanBalanceQueryBean respLoanBalanceQueryBean) throws Exception {
        MsgInfoArry msgInfoArry = new MsgInfoArry();
        //借据号
        msgInfoArry.setDbllNo(a.getBillNo());
        //授信协议编号
        msgInfoArry.setCrAgrmtNo(a.getLmtContNo());
        //贷款号
        msgInfoArry.setLoanNo(a.getLoanSeq());
        //发放号
        msgInfoArry.setDstrNo(a.getDistrNo());

        //借据金额  ContrOriglAmt 合同金额
        msgInfoArry.setDbllAmt(new BigDecimal(respLoanInfoQueryBean.getContrOriglAmt()));
        //借据余额
        msgInfoArry.setDbllBal(Objects.isNull(respLoanBalanceQueryBean.getLoanBal()) ? BigDecimal.ZERO : respLoanBalanceQueryBean.getLoanBal());
        //借据起始日
        msgInfoArry.setDbllStrtDay(DateUtility.format8To10(respLoanBalanceQueryBean.getContrBegDt()));
        //借据到期日
        msgInfoArry.setDbllMtrDay(DateUtility.format8To10(respLoanBalanceQueryBean.getContrEndDt()));
        //借据状态
        msgInfoArry.setDbllSt(AccLoanStatusUtils.transferAccStatusByHj(respLoanInfoQueryBean.getAcctStDsc(), respLoanBalanceQueryBean.getLoanSt()));
        //msgInfoArry.setDbllSt(transferAccStatusByHj(respLoanBalanceQueryBean.getLoanSt()));
        //执行年利率
        msgInfoArry.setExecAnulIntRt(Objects.isNull(respLoanInfoQueryBean.getComIntRate()) ? BigDecimal.ZERO : respLoanInfoQueryBean.getComIntRate().divide(new BigDecimal("100")));
        //浮动利率
        msgInfoArry.setIntRtFlotRto(a.getFloatingRate());
        //贷款期限
        msgInfoArry.setLoanTrm(String.valueOf(a.getLoanTerm()));
        //msgInfoArry.setLmtTrmUnt(cTertType(a.getTermType())); @date 2019/07/15
        //额度期限单位
        msgInfoArry.setIntRtTrmUnit(cTertType(a.getLoadTermType()));
        //还款方式
        msgInfoArry.setRpymtMd(a.getRepaymentMode());
        //产品id
        msgInfoArry.setPdNo(a.getPrdId());
        //渠道编号
        msgInfoArry.setChanNo(a.getChannelCode());
        //银行卡号
        msgInfoArry.setRpymtCardNo(a.getRepaymentAccount());
        //放款卡号
        msgInfoArry.setDistrCardNo(a.getEnterAccount());
        //还款周期
        msgInfoArry.setRpymtCyc(a.getRepayFreq() + a.getRepayFreqUnit());
        //还款日期
        msgInfoArry.setRpymtDt(a.getReturnDate());
        //本金 利息 罚息 复利
        //应还本金
        msgInfoArry.setRcvbIntAcmln(respLoanBalanceQueryBean.getRpyblPrin());
        //已还本金
        msgInfoArry.setRcvbIntAcmln(respLoanBalanceQueryBean.getDstrInfArry()[0].getRpydPrin());
        //应收利息累计 应还利息
        msgInfoArry.setRcvbIntAcmln(respLoanBalanceQueryBean.getRpyblInt());
        //实收利息累计 实收利息
        msgInfoArry.setPclupIntAcmln(respLoanBalanceQueryBean.getDstrInfArry()[0].getRpydInt());
        //拖欠本金的罚息（应收未收） 应收罚息
        msgInfoArry.setRcvbUncolcdPnyInt(respLoanBalanceQueryBean.getRpyblPnyInt());
        //实收罚息 实收罚息
        msgInfoArry.setRpydPnyInt(respLoanBalanceQueryBean.getDstrInfArry()[0].getRpydPnyInt());
        //应收复利累计 应收复利
        msgInfoArry.setRcvbCmpdIntAcmln(respLoanBalanceQueryBean.getRpyblCmpdInt());
        //实收复利 实收复利
        msgInfoArry.setPclupCmpdInt(respLoanBalanceQueryBean.getDstrInfArry()[0].getRpydCmpdInt());

        //计提利息
        msgInfoArry.setPrvnInt(respLoanBalanceQueryBean.getDstrInfArry()[0].getPrvnInt());

        //如果结清的话不查还款计划
        if (!msgInfoArry.getDbllSt().equals(DblStEnum.ENUM_4.getValue()) && !msgInfoArry.getDbllSt().equals(DblStEnum.ENUM_13.getValue())) {
            //互金-还款计划查询
            ReqRepaymentDetailsInfoQueryBean reqRepaymentDetailsInfoQueryBean = new ReqRepaymentDetailsInfoQueryBean();
            reqRepaymentDetailsInfoQueryBean.setAcctNo(a.getLoanSeq());
            reqRepaymentDetailsInfoQueryBean.setDistrNo(a.getDistrNo());
            RespRepaymentPlanListQueryBean respRepaymentPlanListQueryBean = loanInfoQueryService.repaymentPlanListQuery(reqRepaymentDetailsInfoQueryBean, glblSrlNo);
            if (respRepaymentPlanListQueryBean != null && respRepaymentPlanListQueryBean.getAcctDtlInfArry().size() > 0) {
                AcctDtlInfBean nextRepayPlan = getNextRepayPlan(respRepaymentPlanListQueryBean);
                //获取当前的openday
                if (!Objects.isNull(nextRepayPlan)) {
                    //下期还款日期
                    msgInfoArry.setNxtTrmRpymtDt(nextRepayPlan.getEndDt());
                    //下期还款金额
                    msgInfoArry.setNxtTrmRpymtAmt(PloaninfoUtils.getPlanNeedAmt(nextRepayPlan));
                    //剩余期数
                    msgInfoArry.setRmanTrmCnt(a.getLoanTerm().intValue() - Integer.parseInt(nextRepayPlan.getRpyTime()) + 1);
                } else {
                    msgInfoArry.setRmanTrmCnt(0);
                }
            }
            //贷款用途
            msgInfoArry.setLoanPps(a.getLoanUseType());
            //宽限期
            List<MsgInfoArry.AcctDtlInf> graceDateArray = new ArrayList<>();
            for(int i = 0;i<respRepaymentPlanListQueryBean.getAcctDtlInfArry().size();i++ ){
                MsgInfoArry.AcctDtlInf acctDtlInf = new MsgInfoArry.AcctDtlInf();
                acctDtlInf.setGrcPrd(respRepaymentPlanListQueryBean.getAcctDtlInfArry().get(i).getGrcPrd());
                acctDtlInf.setRpymtTrmCnt(respRepaymentPlanListQueryBean.getAcctDtlInfArry().get(i).getRpyTime());
                graceDateArray.add(i,acctDtlInf);
            }
            msgInfoArry.setGrcPrdInfArry(graceDateArray);
            //欠款金额
            BigDecimal notPaidTotal = getNotPaidTotal(respLoanInfoQueryBean, respLoanBalanceQueryBean, respRepaymentPlanListQueryBean, openDay);

            msgInfoArry.setArsAmt(notPaidTotal);
        } else {
            //下期还款金额
            msgInfoArry.setNxtTrmRpymtAmt(BigDecimal.ZERO);
            //剩余期数
            msgInfoArry.setRmanTrmCnt(0);
            msgInfoArry.setArsAmt(BigDecimal.ZERO);
        }
        return msgInfoArry;
    }

    /**
     * 结算借据的欠款金额
     * 欠款金额=欠款本金+欠款利息+欠款罚息+欠款复利-计提利息
     *
     * 欠款本金=应还本金
     * 欠款利息=应还利息+计提利息（取所有借据的计提利息汇总）
     * 欠款罚息=应还罚息
     * 欠款复利=应还复利
     *
     * @param respLoanInfoQueryBean
     * @param respLoanBalanceQueryBean
     * @return
     */
    private BigDecimal getNotPaidTotal(RespLoanInfoQueryBean respLoanInfoQueryBean, RespLoanBalanceQueryBean respLoanBalanceQueryBean, RespRepaymentPlanListQueryBean respRepaymentPlanListQueryBean, String openDate) {

        //应还本金
        //应还利息
        //应还罚息
        //应还复利
        BigDecimal notPaidTotal = PloaninfoUtils.getAddResult(
                respLoanBalanceQueryBean.getRpyblPrin(),
                respLoanBalanceQueryBean.getRpyblInt(),
                respLoanBalanceQueryBean.getRpyblPnyInt(),
                respLoanBalanceQueryBean.getRpyblCmpdInt()
        );
        logger.info("【{}】的借据信息进行欠款统计：应还本金为：[{}]", respLoanInfoQueryBean.getAcctKwd(), respLoanBalanceQueryBean.getRpyblPrin());
        logger.info("【{}】的借据信息进行欠款统计：应还利息为：[{}]", respLoanInfoQueryBean.getAcctKwd(), respLoanBalanceQueryBean.getRpyblInt());
        logger.info("【{}】的借据信息进行欠款统计：应还罚息为：[{}]", respLoanInfoQueryBean.getAcctKwd(), respLoanBalanceQueryBean.getRpyblPnyInt());
        logger.info("【{}】的借据信息进行欠款统计：应还复利为：[{}]", respLoanInfoQueryBean.getAcctKwd(), respLoanBalanceQueryBean.getRpyblCmpdInt());
        //计提利息（取所有借据的计提利息汇总）
        DstrInfArry[] dstrInfArry = respLoanBalanceQueryBean.getDstrInfArry();
        BigDecimal prvnInt = new BigDecimal(0.00);
        if (dstrInfArry != null && dstrInfArry.length > 0) {
            for (int i = 0; i < dstrInfArry.length; i++) {
                prvnInt = PloaninfoUtils.getAddResult(dstrInfArry[i].getPrvnInt());
            }
        }
        notPaidTotal = notPaidTotal.subtract(prvnInt);
        return notPaidTotal;
    }

    /**
     * 获取还款计划未还的金额
     *
     * @param acctDtlInfBean
     * @return
     */
    private BigDecimal getPlanNotPaidTotalAmt(AcctDtlInfBean acctDtlInfBean) {

        DecimalFormat decimalFormat = new DecimalFormat("#.00");
        BigDecimal total = new BigDecimal(0.00);
        if (!Objects.isNull(acctDtlInfBean.getPlanPrin())) {
            total = total.add(new BigDecimal(decimalFormat.format(acctDtlInfBean.getPlanPrin())));
        }
        if (!Objects.isNull(acctDtlInfBean.getPlanInt())) {
            total = total.add(new BigDecimal(decimalFormat.format(acctDtlInfBean.getPlanInt())));
        }
        if (!Objects.isNull(acctDtlInfBean.getIssuePnyInt())) {
            total = total.add(new BigDecimal(decimalFormat.format(acctDtlInfBean.getIssuePnyInt())));
        }
        if (!Objects.isNull(acctDtlInfBean.getIssueCmpdInt())) {
            total = total.add(new BigDecimal(decimalFormat.format(acctDtlInfBean.getIssueCmpdInt())));
        }
/*        if (!Objects.isNull(acctDtlInfBean.getIssueOvdueCmpdInt())) {
            total = total.add(new BigDecimal(decimalFormat.format(acctDtlInfBean.getIssueOvdueCmpdInt())));
        }
        if (!Objects.isNull(acctDtlInfBean.getIssueOvduePnyInt())) {
            total = total.add(new BigDecimal(decimalFormat.format(acctDtlInfBean.getIssueOvduePnyInt())));
        }*/
        if (!Objects.isNull(acctDtlInfBean.getActRpyPrin())) {
            total = total.subtract(new BigDecimal(decimalFormat.format(acctDtlInfBean.getActRpyPrin())));
        }
        if (!Objects.isNull(acctDtlInfBean.getActRpyInt())) {
            total = total.subtract(new BigDecimal(decimalFormat.format(acctDtlInfBean.getActRpyInt())));
        }
        if (!Objects.isNull(acctDtlInfBean.getActRpyPnyInt())) {
            total = total.subtract(new BigDecimal(decimalFormat.format(acctDtlInfBean.getActRpyPnyInt())));
        }
        if (!Objects.isNull(acctDtlInfBean.getActRpyCmpdInt())) {
            total = total.subtract(new BigDecimal(decimalFormat.format(acctDtlInfBean.getActRpyCmpdInt())));
        }
/*        if (!Objects.isNull(acctDtlInfBean.getActRpyOvduePnyInt())) {
            total = total.subtract(new BigDecimal(decimalFormat.format(acctDtlInfBean.getActRpyOvduePnyInt())));
        }
        if (!Objects.isNull(acctDtlInfBean.getActRpyOvdueCmpdInt())) {
            total = total.subtract(new BigDecimal(decimalFormat.format(acctDtlInfBean.getActRpyOvdueCmpdInt())));
        }*/

        return total;
    }

    /**
     * 获取当前期的还款计划(最早的未结清的数据)
     *
     * @param respRepaymentPlanListQueryBean
     * @return
     */
    private final AcctDtlInfBean getNextRepayPlan(RespRepaymentPlanListQueryBean respRepaymentPlanListQueryBean) {
        List<AcctDtlInfBean> acctDtlInfArry = respRepaymentPlanListQueryBean.getAcctDtlInfArry();
        //根据还款期数排序
        Collections.sort(acctDtlInfArry, (o1, o2) -> (Integer.parseInt(o1.getRpyTime()) - Integer.parseInt(o2.getRpyTime())));
        for (AcctDtlInfBean acctDtlInfBean : acctDtlInfArry) {
            BigDecimal planNotPaidTotalAmt = PloaninfoUtils.getPlanNeedAmt(acctDtlInfBean);
            if (planNotPaidTotalAmt.compareTo(BigDecimal.ZERO) > 0) {
                return acctDtlInfBean;
            }
        }
        return null;
    }


    /**
     * 标准
     * 01 天
     * 02 月
     * 03 年
     * 网贷：
     * D 天
     * M 月
     * Y 年
     *
     * @param tertType
     * @return
     */
    private final String cTertType(String tertType) {

        if (StringUtils.isEmpty(tertType)) {
            return "";
        }
        switch (tertType) {
            case "D":
                return "01";
            case "M":
                return "02";
            case "Y":
                return "03";
        }

        return tertType;
    }

    public void setRespPersonalLoanInfo(String pageNo, String pageSize, YedRespPersonalLoanInfo respPersonalLoanInfo, Integer totalSize, ArrayList<MsgInfoArry> loanInfArries) {
        respPersonalLoanInfo.setPgNo((pageNo == null || !pageNo.matches("^[1-9]{1}[0-9]*$")) ? DEFAULT_PAGE_NO : pageNo);
        respPersonalLoanInfo.setTotCnt(totalSize.toString());
        respPersonalLoanInfo.setPerPgDsplCnt((pageSize == null || !pageSize.matches("^[1-9]{1}[0-9]*$")) ? DEFAULT_PAGE_SIZE : pageSize);
        respPersonalLoanInfo.setMsgInfoArryList(loanInfArries);
        respPersonalLoanInfo.setRetCd(EsbSysHeadEnums.RetStEnum.SUCCESS.getCode());
        respPersonalLoanInfo.setRetMsg("查询成功");
    }

    public static void main(String[] args) {
        System.out.println(LocalDate.parse("2020-05-15", DateTimeFormatter.ofPattern("yyyy-MM-dd")).toEpochDay() - LocalDate.parse("20200514", DateTimeFormatter.ofPattern("yyyyMMdd")).toEpochDay() >= 0);
    }

}
